package com.xhwl.centiotdata.handler.pedestrian.impl;

import com.alibaba.fastjson.JSON;
import com.xhwl.centiotdata.handler.pedestrian.PedestrianIntegrationFactory;
import com.xhwl.centiotdata.handler.pedestrian.PedestrianIntegrationHandler;
import com.xhwl.centiotdata.mq.producer.GeneralProducer;
import com.xhwl.centiotdata.pojo.constant.HuaWeiIoTDAConstant;
import com.xhwl.centiotdata.pojo.dto.huawei.PedestrianRecordHuaWeiIoTDADTO;
import com.xhwl.centiotdata.pojo.dto.huawei.PedestrianRecordPersonHuaWeiIoTDADTO;
import com.xhwl.centiotdata.pojo.dto.pedestrian.PedestrianIntegrationConfigDTO;
import com.xhwl.centiotdata.service.cent.IAuthAccountCentService;
import com.xhwl.centiotdata.service.impl.AccountServiceImpl;
import com.xhwl.centiotdata.service.impl.DeviceServiceImpl;
import com.xhwl.centiotdata.suppliersystem.huawei.PedestrianHuaWeiIoTDAHandler;
import com.xhwl.common.constant.cent.pedes.PedestrianConstant;
import com.xhwl.common.dto.auth.PedestrianAuthDTO;
import com.xhwl.common.dto.cent.device.DeviceDTO;
import com.xhwl.common.dto.cent.device.iot.DeviceServiceBody;
import com.xhwl.common.dto.cent.device.iot.IotDeviceJson;
import com.xhwl.common.dto.cent.pedes.AuthDTO;
import com.xhwl.common.dto.cent.pedes.OpenDoorRecordDTO;
import com.xhwl.common.dto.cent.pedes.UserDTO;
import com.xhwl.common.dto.cent.sdata.AccountDTO;
import com.xhwl.common.enums.*;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.pojo.ResultJson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * @Author： lianghz
 * @Description：
 * @Date 2021/10/29/ 15:26
 */
@Slf4j
@Service
public class PedestrianIntegrationHuaWeiIoTDAHandler extends PedestrianIntegrationHandler {

    @Autowired
    private DeviceServiceImpl deviceService;
    @Autowired
    private AccountServiceImpl accountService;
    @Autowired
    private PedestrianHuaWeiIoTDAHandler pedestrianHuaWeiIoTDAHandler;
    @Autowired
    private GeneralProducer generalProducer;
    @Autowired
    private IAuthAccountCentService authAccountCentService;

    public static LinkedBlockingDeque<IotDeviceJson<DeviceServiceBody<PedestrianRecordHuaWeiIoTDADTO>>> deque = new LinkedBlockingDeque<>(1000);

    @Override
    public void afterPropertiesSet() throws Exception {
        PedestrianIntegrationFactory.register(1, this);
    }

    @Override
    public ResultJson createAuth(PedestrianIntegrationConfigDTO configDTO, PedestrianAuthDTO pedestrianAuthDTO) {
        List<String> thirdDeviceIdList = pedestrianAuthDTO.getThirdDeviceIdList();
        if(CollectionUtils.isEmpty(thirdDeviceIdList)){
            return ResultJson.fail("没有选择设备");
        }

        // 查询人员
        List<AccountDTO> accountDTOList = accountService.queryAccount(pedestrianAuthDTO.getProjectId(), Arrays.asList(pedestrianAuthDTO.getSourceId()));
        UserDTO userDTO = new UserDTO();
        AccountDTO accountDTO = accountDTOList.get(0);
        BeanUtils.copyProperties(accountDTO, userDTO);
        userDTO.setUserId(accountDTO.getId().toString());
        //选择一个iot设备发送请求
        configDTO.setUserDeviceId(pedestrianAuthDTO.getIotDeviceIdList().get(0));

        // 新增人员
        String userOpenId = pedestrianHuaWeiIoTDAHandler.userSave(configDTO, userDTO);
        authAccountCentService.save(configDTO.getProjectId(), accountDTO.getId(),userOpenId,null,configDTO.getProductId());
        // 保存授权（卡号与人脸需要调用两次接口）
        AuthDTO authDTO = new AuthDTO();
        authDTO.setUserOpenId(userOpenId);
        authDTO.setCardNumber(!CollectionUtils.isEmpty(pedestrianAuthDTO.getCardNumberList()) ? pedestrianAuthDTO.getCardNumberList().get(0) : null);
        authDTO.setDeviceOpenIdList(thirdDeviceIdList);
        authDTO.setStartTime(pedestrianAuthDTO.getValidStartTime());
        authDTO.setEndTime(pedestrianAuthDTO.getValidEndTime());
        if(!StringUtils.isEmpty(authDTO.getCardNumber())){
            pedestrianHuaWeiIoTDAHandler.pedestrianAuthSave(configDTO, authDTO);
        }
        authDTO.setFaceUrl(pedestrianAuthDTO.getFaceUrl());
        if(!StringUtils.isEmpty(authDTO.getFaceUrl())){
            pedestrianHuaWeiIoTDAHandler.pedestrianAuthSave(configDTO, authDTO);
        }
        try {
            onSavingAuthCards(authAccountCentService, configDTO, pedestrianAuthDTO);
        } catch (Exception e) {
            // 保存转换卡号数据失败
        }
        return ResultJson.success(userOpenId);
    }

    @Override
    public ResultJson updateAuth(PedestrianIntegrationConfigDTO configDTO, PedestrianAuthDTO pedestrianAuthDTO) {
        if (StringUtils.isEmpty(pedestrianAuthDTO.getUserOpenId())) {
            throw new BusinessException("第三方未授权");
        }

        if(!CollectionUtils.isEmpty(pedestrianAuthDTO.getDeletedThirdDeviceIdList())){
            this.deleteAuth(configDTO, pedestrianAuthDTO);
        }

        if (CollectionUtils.isEmpty(pedestrianAuthDTO.getThirdDeviceIdList())){
            return ResultJson.fail("没有选择设备");
        }
        // 查询设备
        List<DeviceDTO> deviceDTOS = null;
        if (!CollectionUtils.isEmpty(pedestrianAuthDTO.getDeviceIdList())) {
            deviceDTOS = deviceService.findDevice(pedestrianAuthDTO.getIndustryId(), null, CategoryEnum.DOOR.getId(), pedestrianAuthDTO.getDeviceIdList());
        }
        //选择一个iot设备发送请求

        // 先删除人员 在新增 去掉人员的旧信息(卡 门禁)
        String userOpenId = pedestrianAuthDTO.getUserOpenId();
        try {
            List<AccountDTO> accountDTOList = accountService.queryAccount(pedestrianAuthDTO.getProjectId(), Arrays.asList(pedestrianAuthDTO.getSourceId()));
            UserDTO userDTO = new UserDTO();
            AccountDTO accountDTO = accountDTOList.get(0);
            BeanUtils.copyProperties(accountDTO, userDTO);
            userDTO.setUserId(accountDTO.getId().toString());
            userOpenId = pedestrianHuaWeiIoTDAHandler.userSave(configDTO, userDTO);
            authAccountCentService.save(configDTO.getProjectId(), accountDTO.getId(), userOpenId, null, configDTO.getProductId());
        }
        catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(!CollectionUtils.isEmpty(pedestrianAuthDTO.getIotDeviceIdList())){
                configDTO.setUserDeviceId(pedestrianAuthDTO.getIotDeviceIdList().get(0));
            }else{
                if(!CollectionUtils.isEmpty(pedestrianAuthDTO.getDeletedIotDeviceIdList())){
                    configDTO.setUserDeviceId(pedestrianAuthDTO.getDeletedIotDeviceIdList().get(0));
                }else{
                    DeviceDTO device = deviceService.findOneDevice(pedestrianAuthDTO.getIndustryId(), pedestrianAuthDTO.getProjectId(), CategoryEnum.DOOR.getId(), new ArrayList<>());
                    configDTO.setUserDeviceId(device.getIotDeviceId());
                }
            }
            // 保存授权（卡号与人脸需要调用两次接口）
            AuthDTO authDTO = new AuthDTO();
            authDTO.setUserOpenId(userOpenId);
            authDTO.setCardNumber(!CollectionUtils.isEmpty(pedestrianAuthDTO.getCardNumberList()) ? pedestrianAuthDTO.getCardNumberList().get(0) : null);
            authDTO.setAddedDeviceOpenIdList(pedestrianAuthDTO.getThirdDeviceIdList());
            authDTO.setDeletedDeviceOpenIdList(pedestrianAuthDTO.getDeletedThirdDeviceIdList());
            authDTO.setStartTime(pedestrianAuthDTO.getValidStartTime());
            authDTO.setEndTime(pedestrianAuthDTO.getValidEndTime());
            if(!StringUtils.isEmpty(authDTO.getCardNumber())){
                pedestrianHuaWeiIoTDAHandler.pedestrianAuthUpdate(configDTO, authDTO);
            }
            // 查询人员
            authDTO.setFaceUrl(pedestrianAuthDTO.getFaceUrl());

            if(!StringUtils.isEmpty(authDTO.getFaceUrl())){
                pedestrianHuaWeiIoTDAHandler.pedestrianAuthUpdate(configDTO, authDTO);
            }
        }
        return ResultJson.success();
    }

    @Override
    public ResultJson deleteAuth(PedestrianIntegrationConfigDTO configDTO, PedestrianAuthDTO pedestrianAuthDTO) {
        //选择一个iot设备发送请求
        if(!CollectionUtils.isEmpty(pedestrianAuthDTO.getDeletedIotDeviceIdList())){
            configDTO.setUserDeviceId(pedestrianAuthDTO.getDeletedIotDeviceIdList().get(0));
        }else{
            DeviceDTO device = deviceService.findOneDevice(pedestrianAuthDTO.getIndustryId(), pedestrianAuthDTO.getProjectId(), CategoryEnum.DOOR.getId(), new ArrayList<>());
            configDTO.setUserDeviceId(device.getIotDeviceId());
        }
        //pedestrianHuaWeiIoTDAHandler.userDelete(configDTO,pedestrianAuthDTO.getUserOpenId());
        AuthDTO authDTO = new AuthDTO();
        authDTO.setUserOpenId(pedestrianAuthDTO.getUserOpenId());
        authDTO.setCardNumber(!CollectionUtils.isEmpty(pedestrianAuthDTO.getCardNumberList()) ? pedestrianAuthDTO.getCardNumberList().get(0) : null);
        authDTO.setDeletedDeviceOpenIdList(pedestrianAuthDTO.getDeletedThirdDeviceIdList());
        authDTO.setStartTime(pedestrianAuthDTO.getValidStartTime());
        authDTO.setEndTime(pedestrianAuthDTO.getValidEndTime());
        if(!StringUtils.isEmpty(authDTO.getCardNumber())){
            pedestrianHuaWeiIoTDAHandler.pedestrianAuthDelete(configDTO, authDTO);
        }
        authDTO.setFaceUrl(pedestrianAuthDTO.getFaceUrl());
        if(!StringUtils.isEmpty(authDTO.getFaceUrl())){
            pedestrianHuaWeiIoTDAHandler.pedestrianAuthDelete(configDTO, authDTO);
        }
        return ResultJson.success();
    }

    @Override
    public void pushRecord(Object data, Integer projectId) {
        if (data instanceof IotDeviceJson) {
            IotDeviceJson<DeviceServiceBody<PedestrianRecordHuaWeiIoTDADTO>> requestBody;
            try {
                requestBody = (IotDeviceJson<DeviceServiceBody<PedestrianRecordHuaWeiIoTDADTO>>) data;
            } catch (Exception e) {
                log.error("pushRecord data transform error ! {}", JSON.toJSONString(data));
                e.printStackTrace();
                return;
            }
            requestBody.getNotify_data().getBody().getServices().stream()
                    .map(deviceService -> deviceService.getProperties())
                    .filter(recordDTO -> HuaWeiIoTDAConstant.RECORD_RESULT_SUCCESS.equals(recordDTO.getDoorrecordRecordType())
                            || HuaWeiIoTDAConstant.RECORD_RESULT_FAILURE.equals(recordDTO.getDoorrecordRecordType()))
                    .forEach(recordDTO -> {
                        OpenDoorRecordDTO openDoorRecordDTO = this.handleRecord(recordDTO, projectId);
                        generalProducer.send(PedestrianConstant.ACCESS_RECORD_TOPIC, openDoorRecordDTO);
                    });
        } else {
            log.error("pushRecord data format error ! {}", JSON.toJSONString(data));
            return;
        }
    }

    private OpenDoorRecordDTO handleRecord(PedestrianRecordHuaWeiIoTDADTO recordHuaWeiIoTDADTO, Integer projectId) {
        PedestrianRecordPersonHuaWeiIoTDADTO doorrecordPerson = null;
        try {
            doorrecordPerson = JSON.parseObject(recordHuaWeiIoTDADTO.getDoorrecordPerson().replaceAll("\\\\", ""), PedestrianRecordPersonHuaWeiIoTDADTO.class);
        } catch (Exception e) {
            log.error("pushRecord doorrecordPerson JSON parse error ! {}", recordHuaWeiIoTDADTO.getDoorrecordPerson());
            e.printStackTrace();
        }
        return OpenDoorRecordDTO.builder()
                .projectId(projectId == null ? recordHuaWeiIoTDADTO.getProjectId() : projectId)
                .openUserId(doorrecordPerson == null ? "" : doorrecordPerson.getPersonNo())
                .userName(doorrecordPerson == null ? "" : doorrecordPerson.getPersonName())
                .openDeviceId(recordHuaWeiIoTDADTO.getDevicesDeviceGuid())
                .deviceName(recordHuaWeiIoTDADTO.getDevicesDeviceName())
                .code(recordHuaWeiIoTDADTO.getDoorrecordRecordId())
                .sourceType(SourceTypeEnum.USER.type)
                .arrivalTime(recordHuaWeiIoTDADTO.getDoorrecordCrossTime())
                .pictureUrl(recordHuaWeiIoTDADTO.getDoorrecordPictureFile())
                .state(this.handleRecordState(recordHuaWeiIoTDADTO.getDoorrecordRecordType()))
                .type(this.handleRecordType(recordHuaWeiIoTDADTO.getDoorrecordEventType()))
                .direction(DirectionEnum.UNKNOWN.getId())
                .approach(AccessApproachEnum.OFF_LINE.getId()).build();
    }

    private Short handleRecordState(String recordType) {
        if (HuaWeiIoTDAConstant.RECORD_RESULT_SUCCESS.equals(recordType)) {
            return 1;
        } else {
            return 0;
        }
    }

    private Short handleRecordType(String eventType) {
        switch (eventType) {
            case HuaWeiIoTDAConstant.RECORD_TYPE_PUBLIC_PASS_WORD:
            case HuaWeiIoTDAConstant.RECORD_TYPE_PRIVATE_PASS_WORD:
                return AccessTypeEnum.PASS_WORD.getId();
            case HuaWeiIoTDAConstant.RECORD_TYPE_BLUETOOTH:
                return AccessTypeEnum.BLUETOOTH.getId();
            case HuaWeiIoTDAConstant.RECORD_TYPE_REMOTE:
                return AccessTypeEnum.REMOTE.getId();
            case HuaWeiIoTDAConstant.RECORD_TYPE_BUTTON:
                return AccessTypeEnum.BUTTON.getId();
            case HuaWeiIoTDAConstant.RECORD_TYPE_IC_CARD:
                return AccessTypeEnum.IC_CARD.getId();
            case HuaWeiIoTDAConstant.RECORD_TYPE_FACE:
                return AccessTypeEnum.FACE.getId();
            case HuaWeiIoTDAConstant.RECORD_TYPE_QR_CODE:
                return AccessTypeEnum.QR_CODE.getId();
            default:
                return AccessTypeEnum.OTHER.getId();
        }
    }

//    @PostConstruct
//    public void consumeRecord() {
//        new Thread(() -> {
//            while (true) {
//                try {
//                    if (deque.size() > 0) {
//                        IotDeviceJson<DeviceServiceBody<PedestrianRecordHuaWeiIoTDADTO>> requestBody = deque.poll();
//                        requestBody.getNotify_data().getBody().getServices().stream()
//                                .map(deviceService -> deviceService.getProperties())
//                                .filter(recordDTO -> HuaWeiIoTDAConstant.RECORD_RESULT_SUCCESS.equals(recordDTO.getDoorrecordRecordType())
//                                        || HuaWeiIoTDAConstant.RECORD_RESULT_FAILURE.equals(recordDTO.getDoorrecordRecordType()))
//                                .forEach(recordDTO -> {
//                                    OpenDoorRecordDTO openDoorRecordDTO = this.handleRecord(recordDTO, null);
//                                    generalProducer.send(PedestrianConstant.ACCESS_RECORD_TOPIC, openDoorRecordDTO);
//                                });
//                    } else {
//                        Thread.sleep(5 * 1000);
//                    }
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            }
//        }).start();
//    }

}
